﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CPPEI.Net
{
    public class PackagePool
    {
        public byte[] Buffer { get; set; }
        private int _offset;
        private bool _isFirst = true;

        /// <summary>
        /// 已经收到的数据长度，每次append会添加，每次update会减少
        /// </summary>
        private int _dataLength;

        public PackagePool()
        {
            Buffer = new byte[10 * 1024 * 1024];
        }

        public Package GetNetBuffer()
        {
            if (Buffer[0] != Package.BeginFlag)
            {
                _offset = 0;
                _dataLength = 0;
                Debug.WriteLine("不是有效的数据包开头，全部清除first:{0}, offset:{1}, datalength:{2}", Buffer[0], _offset, _dataLength);
                return null;
            }
            /*
            int offset = 0;
            byte beginFlag = BufferUtil.ByteFromBuffer(buffer, ref offset);
            byte packageType = BufferUtil.ByteFromBuffer(buffer, ref offset);
            byte scenario = BufferUtil.ByteFromBuffer(buffer, ref offset);
            byte command = BufferUtil.ByteFromBuffer(buffer, ref offset);
            int dataLength = BufferUtil.IntFromBuffer(buffer, ref offset);
            offset += dataLength;
            byte endFlag = BufferUtil.ByteFromBuffer(buffer, ref offset);
            */
            if (_dataLength > Package.HeaderLength)
            {
                int offset = 0;
                byte beginFlag = BufferUtil.ByteFromBuffer(Buffer, ref offset);
                byte packageType = BufferUtil.ByteFromBuffer(Buffer, ref offset);
                byte scenario = BufferUtil.ByteFromBuffer(Buffer, ref offset);
                byte command = BufferUtil.ByteFromBuffer(Buffer, ref offset);
                int dataLength = BufferUtil.IntFromBuffer(Buffer, ref offset);

                if (_dataLength >= Package.HeaderLength + dataLength + Package.EndLength)
                {
                    offset += dataLength;
                    byte endFlag = BufferUtil.ByteFromBuffer(Buffer, ref offset);

                    if (beginFlag == Package.BeginFlag
                        && endFlag == Package.EndFlag)
                    {
                        byte[] packageBuffer = new byte[Package.HeaderLength + dataLength + Package.EndLength];
                        System.Buffer.BlockCopy(Buffer, 0, packageBuffer, 0, packageBuffer.Length);

                        Update(packageBuffer.Length);

                        return new Package(packageBuffer);
                    }
                    else
                    {
                        // 出现了错误，这里不应该出现此情况
                    }
                }
                else
                {
                    Debug.WriteLine("当前数据不够一个包的长度");
                }
            }
            else
            {
                Debug.WriteLine("当前数据不够一个包头的长度");
            }
            return null;
        }

        /// <summary>
        /// 更新buffer的内容，删除第一个包
        /// </summary>
        /// <param name="removeLength">从缓存区前部要删除的数据长度</param>
        private void Update(int removeLength)
        {
            if (removeLength == _dataLength)
            {
                // 
                _offset = 0;
                _dataLength = 0;
                Debug.WriteLine("update package pool 刚好只有一个数据包数据");
            }
            else if (Buffer[removeLength] != Package.BeginFlag)
            {
                _offset = 0;
                _dataLength = 0;
                Debug.WriteLine("update package pool 紧接着的不是包开头，清空");
            }
            else
            {
                for (int index = removeLength; index < _dataLength; index++)
                {
                    Buffer[index - removeLength] = Buffer[removeLength + (index - removeLength)];
                }
                _offset -= removeLength;
                _dataLength -= removeLength;
                Debug.WriteLine("update package pool first:{0}, offset:{1}, datalength:{2}", Buffer[0], _offset, _dataLength);
            }
        }

        public void AppendBuffer(byte[] buffer, int length)
        {
            if (_isFirst)
            {
                int offset = 0;
                byte beginFlag = BufferUtil.ByteFromBuffer(buffer, ref offset);

                if (beginFlag == Package.BeginFlag)
                {
                    // 正确的包开始的头
                    System.Buffer.BlockCopy(buffer, 0, Buffer, _offset, length);
                    _offset += length;
                    _dataLength += length;
                    _isFirst = false;
                }
                else
                {
                    // 第一次必须加载一个正确的包头
                }
            }
            else
            {
                System.Buffer.BlockCopy(buffer, 0, Buffer, _offset, length);
                _offset += length;
                _dataLength += length;
            }
        }
    }
}
